import speech_recognition as sr
import pyttsx3
import datetime
import requests
import json
from playsound import playsound
import tkinter as tk
from tkinter import scrolledtext
import threading
import sys


class VoiceAssistant:
    def __init__(self):
        self.recognizer = sr.Recognizer()
        self.engine = pyttsx3.init()

        # 设置语音速率和音量
        self.engine.setProperty('rate', 180)
        self.engine.setProperty('volume', 1.0)

        # 高德天气API密钥
        self.weather_key = "a33ed0f21fdeb11625473beee8bd081c"

        # 天行数据API密钥
        self.news_key = "cea8bd7ac1823d3157b63b02aca07d8d"

    def listen(self):
        with sr.Microphone() as source:
            print("正在听...")
            audio = self.recognizer.listen(source)
            try:
                text = self.recognizer.recognize_google(audio, language='zh-CN')
                print(f"您说: {text}")
                return text.lower()
            except:
                print("抱歉，我没听清。")
                return ""

    def speak(self, text):
        self.engine.say(text)
        self.engine.runAndWait()

    def get_time(self):
        current_time = datetime.datetime.now()
        return current_time.strftime("%H:%M")

    def get_location_code(self, city="北京"):
        """获取城市编码"""
        try:
            url = f"https://restapi.amap.com/v3/geocode/geo"
            params = {
                "address": city,
                "key": self.weather_key
            }
            response = requests.get(url, params=params)
            data = response.json()
            if data["status"] == "1" and data["geocodes"]:
                return data["geocodes"][0]["adcode"]
            return None
        except:
            return None

    def get_weather(self, city="北京"):
        try:
            # 先获取城市编码
            city_code = self.get_location_code(city)
            if not city_code:
                return "未找到该城市"

            # 获取天气信息
            url = "https://restapi.amap.com/v3/weather/weatherInfo"
            params = {
                "city": city_code,
                "key": self.weather_key
            }
            response = requests.get(url, params=params)
            data = response.json()

            if data["status"] == "1" and data["lives"]:
                weather_info = data["lives"][0]
                return f"{city}当前天气：{weather_info['weather']}，温度{weather_info['temperature']}℃，湿度{weather_info['humidity']}%，风力{weather_info['windpower']}级"
            return "获取天气信息失败"
        except Exception as e:
            return f"获取天气信息出错: {str(e)}"

    def get_news(self):
        try:
            # 使用天行数据的新闻头条API
            url = "http://api.tianapi.com/topnews/index"
            params = {
                "key": self.news_key,
                "num": 5  # 获取5条新闻
            }

            response = requests.get(url, params=params)
            data = response.json()

            if data["code"] == 200:
                news_text = "今日头条：\n"
                for i, news in enumerate(data["newslist"], 1):
                    news_text += f"{i}. {news['title']}\n"
                return news_text
            else:
                return f"获取新闻失败: {data['msg']}"
        except Exception as e:
            return f"获取新闻失败: {str(e)}"


class AssistantGUI:
    def __init__(self):
        self.root = tk.Tk()
        self.root.title("智能语音助手")
        self.root.geometry("600x400")
        self.root.configure(bg='#f0f0f0')

        # 添加窗口关闭事件处理
        self.root.protocol("WM_DELETE_WINDOW", self.on_closing)

        self.assistant = VoiceAssistant()
        self.is_running = False
        self.voice_thread = None

        self.create_widgets()
        self.setup_style()

    def create_widgets(self):
        # 状态标签
        self.status_label = tk.Label(self.root, text="准备就绪", bg='#f0f0f0')
        self.status_label.pack(pady=5)

        # 文本显示区域
        self.text_display = scrolledtext.ScrolledText(self.root, wrap=tk.WORD, height=15)
        self.text_display.pack(padx=10, pady=5, fill=tk.BOTH, expand=True)

        # 按钮框架
        button_frame = tk.Frame(self.root, bg='#f0f0f0')
        button_frame.pack(pady=10)

        # 开始按钮
        self.start_button = tk.Button(button_frame, text="开始", command=self.start_assistant)
        self.start_button.pack(side=tk.LEFT, padx=5)

        # 停止按钮
        self.stop_button = tk.Button(button_frame, text="停止", command=self.stop_assistant, state=tk.DISABLED)
        self.stop_button.pack(side=tk.LEFT, padx=5)

        # 退出按钮
        self.exit_button = tk.Button(button_frame, text="退出", command=self.quit_application)
        self.exit_button.pack(side=tk.LEFT, padx=5)

    def setup_style(self):
        # 配置按钮样式
        button_style = {
            'width': 10,
            'height': 1,
            'bg': '#4CAF50',
            'fg': 'white',
            'font': ('Arial', 10),
            'relief': tk.RAISED,
            'cursor': 'hand2'
        }
        self.start_button.configure(**button_style)
        self.stop_button.configure(**button_style)
        self.exit_button.configure(**button_style)

        # 配置文本显示区域样式
        self.text_display.configure(
            font=('Arial', 10),
            bg='white',
            fg='black',
            relief=tk.SUNKEN
        )

        # 配置状态标签样式
        self.status_label.configure(
            font=('Arial', 10),
            fg='#333333'
        )

    def update_text(self, text):
        self.text_display.insert(tk.END, text + '\n')
        self.text_display.see(tk.END)

    def update_status(self, status):
        self.status_label.config(text=status)

    def quit_application(self):
        self.is_running = False
        self.root.after(1000, self.root.destroy)
        sys.exit()

    def on_closing(self):
        self.is_running = False
        self.root.after(1000, self.root.destroy)
        sys.exit()

    def start_assistant(self):
        if not self.is_running:
            self.is_running = True
            self.text_display.delete(1.0, tk.END)
            self.start_button.config(state=tk.DISABLED)
            self.stop_button.config(state=tk.NORMAL)
            self.voice_thread = threading.Thread(target=self.voice_recognition_thread)
            self.voice_thread.daemon = True
            self.voice_thread.start()

    def stop_assistant(self):
        self.is_running = False
        self.start_button.config(state=tk.NORMAL)
        self.stop_button.config(state=tk.DISABLED)
        self.update_status("准备就绪")

    def voice_recognition_thread(self):
        self.update_text("助手: 您好！我是您的智能语音助手，有什么可以帮您？")
        self.assistant.speak("您好！我是您的智能语音助手，有什么可以帮您？")

        while self.is_running:
            self.update_status("正在听...")
            command = self.assistant.listen()

            if command:
                self.update_text(f"您说: {command}")

                if "再见" in command or "退出" in command:
                    response = "再见！"
                    self.update_text(f"助手: {response}")
                    self.assistant.speak(response)
                    self.stop_assistant()
                    self.root.after(1000, self.quit_application)
                    break

                elif "几点" in command:
                    time = self.assistant.get_time()
                    response = f"现在是{time}"
                    self.update_text(f"助手: {response}")
                    self.assistant.speak(response)

                elif "天气" in command:
                    city = "北京"
                    for word in command.split():
                        if word != "天气" and len(word) >= 2:
                            city = word
                            break
                    weather = self.assistant.get_weather(city)
                    self.update_text(f"助手: {weather}")
                    self.assistant.speak(weather)

                elif "新闻" in command:
                    news = self.assistant.get_news()
                    self.update_text(f"助手: {news}")
                    self.assistant.speak(news)

                elif "谢谢" in command:
                    response = "不客气！"
                    self.update_text(f"助手: {response}")
                    self.assistant.speak(response)

                else:
                    response = "抱歉，我还不能理解这个命令"
                    self.update_text(f"助手: {response}")
                    self.assistant.speak(response)

            self.update_status("准备就绪")

    def run(self):
        self.root.mainloop()


if __name__ == "__main__":
    app = AssistantGUI()
    app.run()